;------------
; My Rutines
; all code by Arcadiy Gobuzov
; E-mail: firegear@mail.ru
;        gobuzov@yahoo.com
;--------------------------------------------
LCDon:
 push af
 ld   a,%10000011       ;7 LCD Controller = RUN
                        ;6 WIN Bank       = $9800
                        ;5 Window         = OFF 
                        ;4 BG Gfx         = $8800
                        ;3 BG Tiles       = $9800
 ldio [$40],a           ;2 OBJ Structure  = 8x8
 pop  af                ;1 OBJ Display    = ON
 ret                    ;0 BG             = ON

;---------
VblankHalt:
 halt
 ld   hl,VblankFlag
 inc  [hl]
 dec  [hl]
 jr   z,VblankHalt
 dec  [hl]
 ret

;----------
halt100:
 ei
 push bc
 ld   b,100
 halt
 dec  b
 jr   nz,@-3 
 pop  bc
 ret
;----------
eii:
 ld   a,%01000100	; set lcdc int
 ldio [$41],a
 xor  a
 ldio [$45],A
 ld   a,%00000011       ; Allow LCDC Status Interrupt & Vertical Blank
 ldio [$FF],a
 ei
 ret
;----------
haltb:
 ei
 halt
 dec  b
 jr   nz,@-3 
 ret
;
haltbv:
 call VblankHalt
 dec  b
 jr   nz,@-4
 ret
;----------
CopyHLtoDEinC:
 ld   b,0
CopyHLtoDE:
 waitvblank
 ld   a,[hli]
 ld   [de],a
 inc  de
 dec  bc
 ld   a,b
 or   c
 jr   nz,CopyHLtoDE
 ret
;
;------ TwoScreenIni ---------------------------------------------------------
; setup window 16x15 tiles on BG Display data 1 and 2
; Char map on 9800 use 240 tiles from Bank 0
; Char map on 9c00 use tiles from Bank 1; WorkScreen:=0;
initApaScr:
 ld   de,$88f           ; first: filling border of screen noused tiles:
 ld   hl,Screen0        ; e=one notused bgtile ($8f)
 ld   c,l
cbord1:
 rst  0
 rst  56
 ld   [hl],e            ; char code
 rst  8
 rst  56
 ld   [hl],c            ; 0 bank, 0 pallete
 set  2,h
 rst  56
 ld   [hl],d            ; 1 bank, 0 pallete
 rst  0
 rst  56
 ld   [hl],e
 res  2,h
 inc  hl
 bit  2,h               ; is hl==$9c00?
 jr   z,cbord1          ; no

 ld   a,$80
 ld   bc,$100f          ; 16 x 15
 ld   de,$0020          ;
 ld   hl,Ywindow*$20+Screen0+Xwindow
scfil0:
 push bc
 push hl
scfil1:
 ld   b,a
 rst  56
 ld   [hl],b            ; char code
 set  2,h
 rst  56
 ld   [hl],b
 ld   a,b
 res  2,h
 inc  a
 add  hl,de
 dec  c
 jr   nz,scfil1
 inc  a
 pop  hl
 inc  l
 pop  bc
 dec  b
 jr   nz,scfil0
 ret

;
initFullScreen:
 rst  0
 ld   de,12
 ld   hl,$9800
 ld   a,l               ; filling char map
 ld   b,$12
ifs1:
 ld   c,$14
ifs11:
 push bc
 ld   c,a
 waitvblank
 ld   [hl],c
 inc  hl
 ld   a,c
 pop  bc 
 inc  a
 dec  c
 jr   nz,ifs11
 add  hl,de
 dec  b
 jr   nz,ifs1
 rst  8
 rst  40
 db   %00111011         ; bc,d,hl
 dw   12*32+16
 db   0
 dw   $9800
 db   $54

 rst  40
 db   %00001001         ; c,d
 db   164
 db   8
 db   $56
 ret

;------------
ClearObjects:
 rst  40
 db   %00111001         ; c,d,hl
 db   $a0
 db   0
 dw   MyObjects
 db   $56
 ret

;-------
FillHLinC
 ld   b,0
FillHL:                 
 waitvblank
 ld   [hl],d            ; bc - counter
 inc  hl                ; d  - filling byte
 dec  bc                ; hl - address
 ld   a,b
 or   c
 jr   nz,FillHL
 ret
;---------------------------
GetAdress:         ; in : bc-coords on screen /x,y E 0..255/
 push bc           ; out: hl-physical addres in vram TILESET
 call getBgAdrFromPix  ; rLCDC checked!
 rst  0
 rst  56
 ld   c,[hl]       ; c=char code
 rst  8
 rst  56
 bit  3,[hl]       ; what bank?
 jr   nz,@+3
 rst  0         
 ld   de,$8000
 ld   h,e
 ldio a,[$40]     ; 0:bg start 8800  since 80 tile
 bit  4,a         ; 1:bg start 8000  since 00 tile
 jr   nz,@+7
 ld   a,c
 sub  d
 ld   c,a
 ld   d,$88  
 ld   l,c
 add  hl,hl        ; *16
 add  hl,hl        ;
 add  hl,hl        ;
 add  hl,hl        ;
 add  hl,de
 pop  bc
 ret
;------------ calculate addr on bg map from pix cords
getBgAdrFromPix:        ; in : bc:coords on bg /x,y E 0..255/
 ld   h,b               ; out: hl:physical addres in vram MAP/rLCDC checking/
 ld   l,c
 srl  l
 srl  l
 srl  l
 srl  h
 srl  h
 srl  h
 dec  l
 dec  h
 dec  h
;------------ calculate addr on bg map
getBgAdr:               ; in : hl:coords on bg /x,y E 0..31/
 push af                ; out: hl:physical addres in vram MAP/rLCDC checking/
 ld   a,l    
 ld   l,h
 ld   h,0
 add  hl,hl             ;
 add  hl,hl
 add  hl,hl             ; *32
 add  hl,hl
 add  hl,hl             ;
 add  a,l
 ld   l,a
 jr   nc,@+3
 inc  h
 ld   a,[rLCDC]
 rra
 and  4
 add  a,$98
 add  a,h
 ld   h,a
 pop  af
 ret

;------------  fill rect /group of tiles/
Rvflip:
 add  hl,de
 dec  b
 jr   nz,@-2
 ld   b,h               ; difference to left-down corner of group of tiles
 ld   c,l
 pop  de                ; chars map
 add  hl,de
 ld   d,h
 ld   e,l               ; right-down corner of Rect /with char map /real
 pop  hl                ; bgmap adr 
 push hl
 push bc                ; difference to start Rect will right-down corner
 call RvertFLIP
 pop  bc                ; difference
 pop  de                ; bgmap adr
 pop  hl                ; atr map of rect
                        ; right-down corner of Rect /attr map /real
 call RFLIPP
RvertFLIP:
 ld   a,[RectXYsize+1]
rvf1:
 push af
 ld   a,[RectXYsize]
 ld   c,a
 ld   a,e
 sub  c
 ld   e,a
 jr   nc,@+3
 dec  d
 push hl
 push de
rvf2:
 call RFLIPJ
 inc  de
 dec  c
 jr   nz,rvf2
 pop  de  
 pop  hl
 call RFLIPK
 pop  af
 dec  a
 jr   nz,rvf1
 ret
RFLIPK:
 ld   a,$20
 add  a,l
 ld   l,a
 ret  nc
 inc  h
 ld   a,h
 and  3
 ret  nz
 dec  h
 dec  h
 dec  h
 dec  h
 ret
RFLIPJ:
 ld   a,[HiTemp2]    ; additional Attributes of tile/0 at CharMap
 ld   b,a
 ld   a,[de]
 xor  b
 and  %01100000
 ld   b,a
 ld   a,[HiTemp2]
 and  %10011111
 or   b
 ld   b,a
 ld   a,[de]
 and  %10011111 
 or   b
 ld   b,a
 ld   a,[HiTemp1]    ; number of first tile/0 at AttrMap
 add  a,b
 ld   b,a
 waitvblank
 ld   [hl],b
 ld   a,l
 and  %11100000
 ld   b,a
 ld   a,l
 inc  a
 and  $1f
 or   b
 ld   l,a
 ret
RFLIPP:
 add  hl,bc             
 exdehl
RFLIPP1:
 rst  8 
 xor  a
 ld   [HiTemp1],a
 ld   a,[RectAttr]
 ld   [HiTemp2],a
 ret
FillRect:
 push bc
 push de
 call FillRect1
 pop  de
 pop  bc
 ret
FillRect1:              ; in :  a-attr of tiles /flips,bgpriority/
 ld   [RectAttr],a      ;      bc-map of attr /palletes or as in 'a'/ 
 rst  0  ; char map set ;      de-map of char 
 call getBgAdr          ;      hl-coords on bg /x,y E 0..31/
 push af                ; at RectXYsize already setted sizes of rect
 ld   a,[RectTile]      ; at RectTile already setted number of first tile    
 ld   [HiTemp1],a       ; number of first tile of Rect  
 xor  a
 ld   [HiTemp2],a       ; additional atributes in AttrMap / for charmap 0
 pop  af
 rra                    
 swap a
 and  3                 ; now checking flip flags:
 push bc                ; attr map
 jr   z,Rnoflip
 push hl                ; bgmap adr
 push de                ; chars map
 ld   hl,RectXYsize
 ld   c,[hl]            ; width
 inc  hl                ;
 ld   b,[hl]            ; height
 ld   d,0
 ld   e,c
 ld   h,d
 ld   l,d
 dec  a
 jr   z,Rhflip
 dec  a
 jp   z,Rvflip
;both flip
 dec  c
 dec  b
 jr   z,@+6
 add  hl,de
 dec  b
 jr   nz,@-2
 add  hl,bc
 ld   b,h
 ld   c,l
 pop  de                ; chars map
 add  hl,de
 ld   d,h
 ld   e,l               ; right-down corner of Rect
 pop  hl                ; bgmap adr 
 push hl
 push bc                ; add to start Rect will right-down corner
 call RbothFLIP
 pop  bc                ; difference
 pop  de                ; bgmap adr
 pop  hl                ; atr map of rect
 call RFLIPP
RbothFLIP:
 ld   b,a
 ld   a,[RectXYsize+1]
rbf1:
 push af
 ld   a,[RectXYsize]
 ld   c,a
 push hl
rbf2:
 call RFLIPJ
 dec  de
 dec  c
 jr   nz,rbf2
 pop  hl
 call RFLIPK
 pop  af
 dec  a
 jr   nz,rbf1
 ret                    ; zx
;
Rnoflip: 
 xor  a
 push hl                ; bgmap adr
 call RnoFLIP
 pop  hl                ; bgmap adr
 pop  de                ; atr map of rect
 call RFLIPP1
RnoFLIP:
 ld   a,[RectXYsize+1]
rnf1:
 push af
 ld   a,[RectXYsize]
 ld   c,a
 push hl
rnf2:
 call RFLIPJ
 inc  de
 dec  c
 jr   nz,rnf2
 pop  hl
 call RFLIPK
 pop  af
 dec  a
 jr   nz,rnf1
 ret
Rhflip:
 dec  c
 ld   b,a               ; b=0
 pop  hl                ; chars map
 add  hl,bc
 ld   d,h
 ld   e,l
 pop  hl                ; bgmap adr
 push hl                ; bgmap adr
 push bc                ; difference
 call RhorizFLIP        ; b=already 0

 pop  bc                ; difference
 pop  de                ; bgmap adr
 pop  hl                ; atr map of rect
 call RFLIPP
RhorizFLIP:
 ld   a,[RectXYsize+1]
rhf1:
 push af
 ld   a,[RectXYsize]
 ld   c,a
 push hl
 push de
rhf2:
 call RFLIPJ
 dec  de
 dec  c
 jr   nz,rhf2
 pop  de
 ld   a,[RectXYsize]
 add  a,e
 ld   e,a
 jr   nc,@+3
 inc  d
 pop  hl
 call RFLIPK
 pop  af
 dec  a
 jr   nz,rhf1
 ret

;-------
getRand;                ; in  a - number
 push de                ; out a - rnd,no bigger input number!
 ld   e,a
getRand1:
 call getRnd
 cp   e
 jr   nc,getRand1
 pop  de
 ret
;------
getRnd:                 ; out a - rnd
 push bc
 push af
 pop  bc
 ld   a,[rndStore]
 rrc  a
 xor  c
 add  a,b
 ld   b,a
 ldio a,[$8b]
 sub  c
 rra
 add  a,b
 ld   b,a
 ldio a,[$05]
 xor  b
 ld   [rndStore],a
 pop  bc
 ret
;--------------- Flashing colors / from black=>real 
ColorFlashing:
 push bc                ; in : b: how many colors
 push de                ;     de: const palletes
 push hl                ;     hl: vars palletes
 ld   a,[hli]
 ld   b,[hl]
 call decomposePal
 push af                ; a=blue
 push hl                ; l=red; h=green
 ld   h,d
 ld   l,e
 ld   a,[hli]
 ld   b,[hl]
 call decomposePal
 pop  de                ; e=red; d=green  | variables
 pop  bc                ; b=blue          |
 cp   b                 ; a=blue const
 jr   z,@+3
 inc  b
 ld   a,e
 cp   l
 jr   z,@+3             ; red  
 inc  e
 ld   a,d
 cp   h
 jr   z,@+3             ; green
 inc  d
 ld   a,b
 call composePal
 pop  hl
 ld   [hli],a
 ld   a,b
 ld   [hli],a
 pop  de
 inc  de
 inc  de
 pop  bc
 dec  b
 jr   nz,ColorFlashing
 ret
;--------------- Fading colors / from real=>black
ColorFading:
 push bc                ; in : b: how many colors
 push hl                ;     hl: vars palletes
 ld   a,[hli]
 ld   b,[hl]
 call decomposePal
 or   a
 jr   z,@+3
 dec  a
 inc  l
 dec  l
 jr   z,@+3
 dec  l
 inc  h
 dec  h
 jr   z,@+3
 dec  h
 ld   d,h
 ld   e,l 
 call composePal
 pop  hl
 ld   [hli],a
 ld   a,b
 ld   [hli],a
 pop  bc
 dec  b
 jr   nz,ColorFading
 ret
;--------------- Diving colors / from real=>white
ColorDiving:
 push bc                ; in : b: how many colors
 push hl                ;     hl: vars palletes
 ld   a,[hli]
 ld   b,[hl]
 call decomposePal
 ld   b,31
 cp   b
 jr   z,@+3
 inc  a
 ld   c,a
 ld   a,l
 cp   b
 jr   z,@+3
 inc  l
 ld   a,h
 cp   b
 jr   z,@+3
 inc  h
 ld   d,h
 ld   e,l
 ld   a,c
 call composePal
 pop  hl
 ld   [hli],a
 ld   a,b
 ld   [hli],a
 pop  bc
 dec  b
 jr   nz,ColorDiving
 ret

;
composePal:             ; in : e: Red
 rlca                   ;      d: Green
 rlca                   ;      a: Blue
 ld   b,a               ; out: a: Low byte of pal
 ld   a,d               ;      b: High byte
 rrca                   
 rrca                   
 rrca
 ld   d,a
 and  3
 or   b
 ld   b,a
 ld   a,d
 and  %11100000
 or   e
 ret
;
decomposePal:           ; in : a: Low byte of pal
 ld   c,a               ;      b: High byte
 and  31                ; out: LHA=RGB
 ld   l,a       ; red
 ld   a,b
 rla
 rla
 rla
 and  %00011000
 ld   h,a
 ld   a,c
 rlca
 rlca
 rlca
 and  7
 or   h
 ld   h,a       ; green
 ld   a,b
 rra
 rra
 and  31        ; blue
 ret

;--------------- set monoPalette; 
SetMonoBkgPal:          ; in  a- index of pal /0      
 or   a                 ;     b- how many colors /32 all
 rla                    ;    de- mask of colors: 0bbbbbgg,gggrrrrr
 rla                    ;    hl- start of monoPalette /only one color-component
 rla
 or   128
 ld   c,a
 waitvblank
 ld   a,c
 ldio [$68], a          ; increment Store in Bkg Write Specification register
smbp1:
 ld   a,[hl]
 rrca  
 rrca  
 rrca
 ld   c,a
 and  %11100000
 or   [hl]
 and  e
 push af
 waitvblank
 pop  af
 ldio [$69],a           ; Background Write Register
 ld   a,c
 and  3
 ld   c,a
 ld   a,[hli]
 rla
 rla
 and  %01111100
 or   c
 and  d
 ld   c,a
 waitvblank
 ld   a,c
 ldio [$69],a           ; Background Write Register
 dec  b
 jr   nz,smbp1
 ret
;------------------------------
SetBkgPalette:          ;in  a - index of palitra
                        ;    b - number of bytes
                        ;    hl- ur colors 
 or   a                 ; just carry off
 rla
 rla
 rla
 or   128               ; auto
 ld   c,a
 waitvblank
 ld   a,c
 ldio [$68], a          ; increment Store in Bkg Write Specification register
ploop1:
 waitvblank
 ld   a,[hli]           ; Store low byte, then high byte in 
 ldio [$69],a           ; Background Write Register
 dec  b
 jr   nz, ploop1
 ret

SetObjPalette:          ; in a - index of palitra
 push af                ;    b - number of bytes
 push bc                ;   hl - ur colors 
 push hl
 or   a                 ; just carry off
 rla
 rla
 rla
 or   128               ; auto
 ld   c,a
 waitvblank
 ld   a,c
 ldio [$6a], a          ; increment Store in Obj Write Specification
                        ; register
ploop2:
 waitvblank
 ld   a,[hli]
 ldio [$6b],a           ; Object Write Register
 dec  b
 jr   nz, ploop2
 pop  hl                ; grey 0=00 (Black/Transparent)
 pop  bc
 pop  af
 ret


;*** this returns an 8 bit value of the pressed keys in [Keys]
;    bits are highactive now
;    start.select.B.A.Down.Up.Left.Right


GetKeys:ld	a,%00010000
	ldio    [$00],a
	ldio    a,[$00]		;sondertasten
	cpl			;high-aktiv
	swap	a		;ins high nibble
	and	%11110000
	ld	b,a
	
	ld	a,%00100000	;joystick
	ldio    [$00],a
	ldio    a,[$00]
	cpl
	and	%00001111
	or	b

	ld	[Keys],a
	ret

;-------------------------remove or correct later
;
SetObjectFull:
; Set object x, y, and character. ;in: c - coordinate x
                                  ;    b - coordinate y
                                  ;    e - character
                                  ;    d - attributes
                                  ;    a - index of object in table
 push bc
 call SetObject
 ld   c,d
 call SetObjectPal
 pop  bc
 ret

;---------
; Set object x, y, and character. ;in: c - coordinate x
                                  ;    b - coordinate y
                                  ;    e - character
                                  ;    a - index of object in table
SetObject:
 push bc
 call SetObjectX        ; Already set up for SetObjectX. Call routine
 ld   c,b               ; Transfer y position into c
 call SetObjectY        ; Call routine
 ld   c,e               ; Transfer character number into c
 call SetObjectChar     ; Call routine
 pop  bc
 ret

;----------
SetObjectX:             ; in :  c - coordinate x
 push bc                ;       a - index of object in table
 ld   b,1
SetObjOb
 call SetObjSome
 pop  bc
 ret

;---------
SetObjectY:             ; in :  c - coordinate y
 push bc                ;       a - index of object in table
 ld   b,0
 jr   SetObjOb

;------------
SetObjectPal:           ; in:  c - palitra
 push bc                ;      a - index of object in table
 ld   b,3
 jr   SetObjOb

;-------------
SetObjectChar:          ; in:  c - character
 push bc                ;      a - index of object in table
 ld   b,2
 call SetObjSome
 pop  bc
 ret

;----------
SetObjSome:
 push af
 push hl
 add  a, a              ; Multiplies a by 4
 add  a, a
 add  a, b              ; Add some bytes [0-3]
 ld   h,MyObjects/256
 ld   l, a
 ld   [hl], c           ; Transfer
 pop  hl
 pop  af
 ret

;-------------
GetObjectInfo:          ; in  a  - index of object
                        ; out bc - coords
                        ;     de - attributes
 push af
 push hl
 add  a,a
 add  a,a
 ld   h,MyObjects/256
 ld   l,a
 ld   b,[hl]            ; y
 inc  hl
 ld   c,[hl]            ; x
 inc  hl
 ld   e,[hl]
 inc  hl
 ld   d,[hl]
 pop  hl
 pop  af
 ret

;------------
PrintHLobjects          ; in:  hl - begin of list,at the end $ff
                        ;      bc - coords of first (pix); will c+=8 
                        ;      d  - pallete+ atr of obj.
                        ;      a  - number of first obj
phao1:                  
 ld   [brezTemp],a
 ld   a,[hli]
 inc  a
 ret  z
 sub  33
 jr   z,@+4
 sub  19
 ld   e,a
 ld   a,[brezTemp]
 call SetObjectFull
 ld   e,a
 ld   a,c
 add  a,8
 ld   c,a
 ld   a,e
 inc  a
 jr   phao1

;-------------------------
PrintHLasObjects:       ; in:  bc - coords on screen (pix)
                        ;      de - number of first object/ d - palitra
                        ;      hl - 16 bit number
 push bc
 push de
 call GetCifres
 pop  de
 pop  bc
 ld   a,e
 ld   e,5
 ld   hl,numBuf+3
 jr   phao1

GetCifres:              ;in : hl - 16bites number
 ld   bc,numBuf         ;     bc - numBuf
 ld   de,-10000         ;     at numBuf 5 figures
 call getCifra
 ld   de,-1000
 call getCifra
 ld   de,-100
 call getCifra
 ld   de,-10
 call getCifra
 ld   de,-1

;--------
getCifra:
 ld   a,52
getcifra1:
 inc  a
 add  hl,de
 jr   c,getcifra1
 ld   [bc],a
 inc  bc
 ld   a,d
 cpl  
 ld   d,a
 ld   a,e
 cpl
 ld   e,a
 inc  de
 add  hl,de
 ret
